<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>requestIdleCallback</title>
  </head>
  <body>
    <script>
      function sleep(delay) {
        for (let now = Date.now(); Date.now() - now < delay; ) {}
      }
      let allStart = 0;
      const works = [
        () => {
          allStart = Date.now();
          console.log("this first work start");
          sleep(20);
          console.log("this first work end");
        },
        () => {
          console.log("this second work start");
          sleep(10);
          console.log("this second work end");
        },
        () => {
          console.log("this third work start");
          sleep(10);
          console.log("this third work end");
          console.log(Date.now() - allStart);
        },
      ];

      requestIdleCallback(workLoop, { timeout: 1000 });
      // deadline参数是一个对象，有2个属性
      //  timeRemaining(), 返回此帧还剩下多少时间让用户使用
      //  didTimeout 判断回调任务callback是否超时
      function workLoop(deadline) {
        console.log(`this frame remainTime is ${deadline.timeRemaining()}`);
        // deadline.timeRemaining() > 0 说明还有剩余时间
        // deadline.didTimeout说明任务已经过期，则必须执行
        while (
          (deadline.timeRemaining() > 0 || deadline.didTimeout) &&
          works.length > 0
        ) {
          performUnitOfWork();
        }
        if (works.length > 0) {
          console.log(`this frame remainTime is ${deadline.timeRemaining()}，时间片已经到期，等待下次调度`);
          window.requestIdleCallback(workLoop, { timeout: 1000 });
        }
      }
      function performUnitOfWork() {
        works.shift()();
      }
    </script>
  </body>
</html>
